package com.ljy.my_study.json转对象.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.*;
import java.util.stream.Collector;

/** 
* @author James
* @date 2018年6月19日 
*/
public class Json2ClassBuilder {
	public static void createBeanFile(String rootBeanName,Map<String,Object> map,String packageUrl,String filePath) throws IOException {
		List<ParamNode> paramNodeList= ParamNodeCreater.getParamNodeList(rootBeanName, map);
		for(ParamNode pn:paramNodeList) {
			if((List<ParamNode>)pn.getObj()==null){
				continue;
			}
			doCreateBeanFile((List<ParamNode>)pn.getObj(),pn.getClassName(),packageUrl,filePath);
		}
	}
	
	public static void doCreateBeanFile(List<ParamNode> tcList,String beanName,String packageUrl,String filePath) throws IOException {
		File file=checkFile(beanName,filePath);
		StringBuilder sb=new StringBuilder();
		createPackageUrl(sb,packageUrl);
		createImportList(sb,tcList);
		createBody(sb,beanName,tcList);
		PrintWriter pw=new PrintWriter(new OutputStreamWriter(new FileOutputStream(file)));
		pw.append(sb);
		pw.flush();
		pw.close();
	}
	
	public static File checkFile(String beanName,String filePath) throws IOException {
		File file=new File(filePath,beanName+".java");
		if(file.exists()) {
			file.delete();
		}
		file.createNewFile();
		return file;
	}
	
	public static void createPackageUrl(StringBuilder sb,String packageUrl) {
		sb.append("package "+packageUrl+";");
		sb.append("\n\n");
	}
	
	public static void createImportList(StringBuilder sb,List<ParamNode> tcList) {
		if(tcList==null){
			return;
		}
		Set<String> importList=new HashSet<>();
		tcList.forEach(tc->{
			if(tc==null||tc.getClassName()==null) return;
			System.out.println(tc);
			System.out.println(tc.getClassName());
			String className=tc.getClassName().toLowerCase();
			if(className.contains("date")) {
				importList.add("import java.util.Date;");
			}else if(className.contains("list")) {
				importList.add("import java.util.List;");
			}
			importList.add("import com.alibaba.fastjson.annotation.JSONField;");
		});
		importList.forEach(i->{
			sb.append(i).append("\n");
		});
		sb.append("\n");
	}

	public static void createBody(StringBuilder sb,String beanName,List<ParamNode> tcList) {
		sb.append("public class "+beanName+" {").append("\n");
		StringBuilder setAndGetSb=new StringBuilder();
		tcList.forEach(tc->{
			String type=tc.getClassName();
			if(type==null) return;
			if(type.equals("List")) {
				String listSubClassName=tc.getListSubClassName();
				type="List<"+listSubClassName+">";
			}
			if(tc.getDesc()!=null&&!tc.getDesc().isEmpty()){
				String[] descArr=tc.getDesc().split("\n");
				sb.append("\t/**\n");
				for(String d:descArr){
					sb.append("\t * " + d+"\n");
				}
				sb.append(" \t*/\n");
			}
			//可以设置成策略模式，不过策略使用不同的字段（蛇形或驼峰）
//			sb.append("\t@JSONField(name=\""+changeFieldName(tc.getFieldName())+"\")\n");
			sb.append("	private "+type+" "+tc.getFieldName()+";\n\n");
			
			String methodName=tc.getFieldName().substring(0, 1).toUpperCase()+tc.getFieldName().substring(1);
			setAndGetSb.append("	public void set"+methodName+"("+type+" "+tc.getFieldName()+") {\n");
			setAndGetSb.append("		this."+tc.getFieldName()+"="+tc.getFieldName()+";\n");
			setAndGetSb.append("	}\n\n");
			setAndGetSb.append("	public "+type+" get"+methodName+"() {\n");
			setAndGetSb.append("		return this."+tc.getFieldName()+";\n");
			setAndGetSb.append("	}\n\n");
		});
		sb.append(setAndGetSb.toString());
		sb.append("}");
	}

	private static String changeFieldName(String fieldName){
		List<Character> list=new ArrayList<>();
		char[] chars=fieldName.toCharArray();
		for(int i=0;i<chars.length;i++){
			if(i==0){
				list.add(Character.toUpperCase(chars[0]));
			}else{
//				65~90
				if(chars[i]>='A'&&chars[i]<='Z'){
					list.add('_');
				}
				list.add(chars[i]);
			}
		}
		char[] result=new char[list.size()];
		for(int i=0;i<result.length;i++){
			result[i]=list.get(i);
		}
		return String.valueOf(result);
	}
}
